package cssOrder.plugin;

/*
 * Copyright 2001-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Echos an object string to the output screen.
 * @goal order
 * @requiresProject false
 */
 
public class Order extends AbstractMojo
{
    /**
     * Any Object to print out.
     * @parameter expression="${order.cssDirectory}" default-value="/"
     */
    private Object cssDirectory;

    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        
        String sourceDirectory = cssDirectory.toString();
		ArrayList<String> fileList = new ArrayList<String>(getFiles(sourceDirectory));
        CSSValidation CSSValidator = new CSSValidation();
		getLog().info( "cssOrder : \n" );
		for(int i = 0; i < fileList.size(); i++) {
			
			String fileName = fileList.get(i);
            String CSS = readCSS(fileName);
			ArrayList<String> errors = new ArrayList<String>(CSSValidator.validateCSSOrder(fileName , CSS));
			if(errors.size() > 0) {
				
				getLog().error(generateReadableError(errors, fileName));
                throw new MojoFailureException( "CSS is disorganised");
				
			}
			
		}
		getLog().info( "\n\n Scanned " + fileList.size() + " files in "+ sourceDirectory +" ." );
    }
    
	
	private static ArrayList<String> getFiles( String sourceDirectory) {
		ArrayList<String> fileList = new ArrayList<String>();
		File sourceDir = new File(sourceDirectory);
		File[] listFiles = sourceDir.listFiles();
		if(!(listFiles == null)) {
			for (int i = 0; i < listFiles.length; i++) {
				
				File currentFile = listFiles[i];
				
				if(!currentFile.isDirectory()) {
					
					String fileName = currentFile.getName();
					if(fileName.contains(".css")) {
						
						fileList.add(sourceDirectory+"/"+fileName);

					}
				}
			}
			
		}
		
		return fileList;
	}
	
	private static String readCSS( String filename ) {
		String LS = System.getProperty("line.separator");
		StringBuffer fileContents = new StringBuffer();
		
		try {
			FileReader fr = new FileReader(filename);
			BufferedReader reader = new BufferedReader(fr);
			String line;
			while((line = reader.readLine()) != null) {
				if(!line.contains("charset")) {
					
					fileContents.append(line).append(LS);
					
				} else {
                
                    fileContents.append(LS);
                
                }
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return removeComments(fileContents.toString());
	}
	
	private static String generateReadableError (ArrayList<String> errors, String filename) {
		String readableErrors = errors.size()+" errors in "+filename+"\n \n";
		
		for(int i = 0; i<errors.size(); i++) {
			
			readableErrors = readableErrors + errors.get(i)+"\n";
			
		}
		
		return readableErrors;
	}
    
    private static String removeComments (String data) {
		
		String [] splitString = data.split("");
		String cleanData = "";
		boolean inCommentBlock = false;
		
		for(int i = 0; i < splitString.length; i++) {
			
			if(inCommentBlock) {
				
				if(splitString[i].equals("/") && splitString[i-1].equals("*")) {
					
					inCommentBlock = false;
					
				} else if (splitString[i].equals("\n")) {
					
					cleanData += "\n";
					
				}
				
			} else {
				
				if(splitString[i].equals("/") && splitString[i+1].equals("*")) {
					
					inCommentBlock = true;
					
				} else {
					
					cleanData += splitString[i];
					
				}
				
			}
			
		}
		return cleanData;
	}
}
